package cmd

import (
	"cdzhmc.com/go-mc/micro/broker"
	"cdzhmc.com/go-mc/micro/client"
	"cdzhmc.com/go-mc/micro/registry"
	"cdzhmc.com/go-mc/micro/server"
	"cdzhmc.com/go-mc/micro/transport"
	"context"
)

type Options struct {
	// For the Command Line itself
	Name        string
	Description string
	Version     string

	// We need pointers to things so we can swap them out if needed.
	Broker   *broker.Broker
	Registry *registry.Registry
	//Selector  *selector.Selector
	Transport *transport.Transport
	Client    *client.Client
	Server    *server.Server
	//Runtime   *runtime.Runtime
	//Store     *store.Store
	//Tracer    *trace.Tracer
	//Auth *auth.Auth

	Brokers    map[string]func(...broker.Option) broker.Broker
	Clients    map[string]func(...client.Option) client.Client
	Registries map[string]func(...registry.Option) registry.Registry
	//Selectors  map[string]func(...selector.Option) selector.Selector
	Servers    map[string]func(...server.Option) server.Server
	Transports map[string]func(...transport.Option) transport.Transport
	//Runtimes   map[string]func(...runtime.Option) runtime.Runtime
	//Stores     map[string]func(...store.Option) store.Store
	//Tracers    map[string]func(...trace.Option) trace.Tracer
	//Auths map[string]func(...auth.Option) auth.Auth

	// Other options for implementations of the interface
	// can be stored in a context
	Context context.Context
}

type Option func(*Options)

func Name(n string)Option  {
	return func(o *Options) {
		o.Name = n
	}
}

func Description(d string) Option {
	return func(o *Options) {
		o.Description = d
	}
}

func Version(v string) Option {
	return func(o *Options) {
		o.Version = v
	}
}

func Broker(b *broker.Broker) Option {
	return func(o *Options) {
		o.Broker = b
	}
}

//func Selector(s *selector.Selector) Option {
//	return func(o *Options) {
//		o.Selector = s
//	}
//}

func Registry(r *registry.Registry) Option {
	return func(o *Options) {
		o.Registry = r
	}
}

func Transport(t *transport.Transport) Option {
	return func(o *Options) {
		o.Transport = t
	}
}

func Client(c *client.Client) Option {
	return func(o *Options) {
		o.Client = c
	}
}

func Server(s *server.Server) Option {
	return func(o *Options) {
		o.Server = s
	}
}

//func Tracer(t *trace.Tracer) Option {
//	return func(o *Options) {
//		o.Tracer = t
//	}
//}